1. use ELIPSES in structure specification, to make sure that underflow is
intentional, or to allow non-0 initialization for fills.

3. Implement a C -> C compiler which inserts inline GDB statements.
This will hurt optimization, but may allow for much freer debugging.
Also implies determining on what level exactly that GDB statements are
generated.

4. C virtual machine (infinite regs and cast operators?)

5. Make multi-type machine insns. This may match faster than normal
insn recog phase. (Using bits for disjuntive decisions.

12. #compiler directives to control compiler behavior on a more
fine-grained level, such as function optimizations, framepointer
req.s, etc.

30. Look at syntax more closely to fix up all those s/r conflicts.
Make sure that C++ syntax is reasonably well implemented.

48. Look into places where arrays can replace lists (such as in
holding the method lists).  Sort these lists or build hash tables for
them.  (Actually, this may not yet be important, as profiling
data does not yet implicate method lookup as a significant waste of
time.)

52. How to make GDB understand operator overloading...

59. Optimized bitfield accesses such as TREE_X (X) && TREE_Y (X) &&
TREE_Z (X) as bit operation.

64. Associator for CSE

67. How does one distinguish between a declaration of a function
taking no arguments from a call to a constructor which takes no
arguments?

70. p. 283: the base of a derived struct is public. What does this
mean now that visibility control can be on a per-element basis?

72. How do we make operator[](), operator()(), and operator->()
members-only functions?

73. The strategy for doing overloaded operators is to have pointer
from an aggregate type to an op table.  If this pointer is NULL, then
no operator overloading to check.  Otherwise, the op table is a hash
table, which suitably indexed by the function, will yield the current
list of argument lists that we can accept.  These argument lists are
hashed to save space (and some time).

77.  Look at making typenames stackable by recovering shadowed
declarations from the tags (during poplevel) back to the TREE_TYPE of
the IDENTIFIER_NODES.

81.  Handle gotos crossing (into, out of, across) scopes that have
calls to constructors.  i.e. either implement the feature or disallow
it.  Right now it is only a bug.

83.  In some situations it is possible to optimize virtual functions,
making them either direct calls, or actually calling them inline!
Identifier the cases where this may be done, and implement this
optimization.  Currently, if a variable has decidedly static type
(i.e., it is a VAR_DECL of aggregate type), then calls through the
virtual function table are eliminated.  This could be extended to use
flow analysis to help with pointers.  Doing PARM_DECLs might be very
hard.

84.  In C++, declaring something like "const int i = 5;" has the same
effect as saying "#define i 5", but not quite, since `i' actually needs
to live somewhere, in case someone else wants to takes its address or
something.  This leads to a possible conflict of interest for
grokdeclarator, which wants to either return a VAR_DECL or a
CONST_DECL.  How does this wash with ANSI C?

87.  Implement multiple inheritance.

88.  Make default parameters for inline functions live on the
permanent obstack in a more natural fashion.

89.  Should default parameter specifications be permitted to refer to
other parameters in the list? I.e., should "f (int a = 0, int b = a + 5)"
be a permissable declaration?

90.  When passing a struct to a function, if that struct has a virtual
function table pointer, then that pointer must be guaranteed to be
accurate for the body of the function, which means that after passing
that parameter, the stack should probably be fixed up as well.

93.  Set a bit on nodes which says whether default-conversion has been
called for that node or not.  This would mean that any type-altering
actions (which are by-and-large rare) would need to be more careful,
but it might help speed up the front-end.

97.  Use obstacks for processing overloaded function names and inline
function definitions.

99.  When using reference types, two kinds of temporary variables are
needed.  One whose scope is the scope of a block, one whose scope is
the scope of a stmt.  The latter is needed when a function takes
reference parameters, and those references exist only for the calling
of that function.

105.  Applying the maxim "Same sh*t, different day" to compiler
implementation, we note that when initializing or destroying
aggregates, the tree structure we create for such actions is always
the same for any given type, only the address we are operating on
changes.  Memoize the tree structure for each type, so that init and
delete code can be generated efficiently, without large walks.
In fact, we might even want to memoize the rtl code for this for real
speed.

109.  Reimplement operator new and operator delete.  Reimplement the
machinery that groks overloaded operator declarations.  Right now
there is precious little error checking.

110.  Attach a pseudo-variable to all pointers to aggregate objects
which is a pointer to its virtual function table.  CSE can be told
that it is a pointer to constant storage.  If the base pointer is not
assigned during its lifetime, then virtual function references can be
made more efficiently.  This would be more general than the current
hack (of treating `this' as constant).

111.  Generate efficient (and expected) code for constructs of the
form "X x = X (args)".  Though this should be equivalent to "X x (args)", 
the current implementation make it behave like "X t (args); X x = t;".
This code could cause some programs to fail if they do not have X(X&)
defined.

112.  Look at overloading functions based on their return type.

